<template>
  <div
    class="echart"
    ref="Echarts"></div>
</template>

<script setup lang="ts">
import * as echarts from 'echarts'
import { ref, onMounted, onUnmounted, computed, PropType, watch, nextTick } from 'vue'

const props = defineProps({
  title: {
    type: String,
    default: ''
  },
  zoomStart: {
    type: Number,
    default: 0
  },
  zoomEnd: {
    type: Number,
    default: 100
  },
  magicType: {
    type: Boolean,
    default: true
  },
  titleColor: {
    type: String,
    default: '#333'
  },
  AxisColor: {
    type: String,
    default: '#333'
  },
  xAxisData: {
    type: Array,
    default: () => []
  },
  yAxisData: {
    type: Array as PropType<{ name: string; data: number[] }[]>,
    default: () => []
  },
  legendData: {
    type: Array as PropType<string[]>,
    default: () => []
  }
})

const Echarts = ref<any>(null)
const emits = defineEmits(['custom-dbclick', 'custom-rect'])

const windowWidth = ref(window.innerWidth)
const deviceRatio = computed(() => windowWidth.value / 1920)
const option = computed(() => {
  return {
    title: {
      text: `${props.title}辐照度功率图`,
      left: 'center',
      top: 5 * deviceRatio.value,
      textStyle: {
        fontSize: 20 * deviceRatio.value,
        color: props.titleColor
      }
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      },
      textStyle: {
        fontSize: 14 * deviceRatio.value
      }
    },
    toolbox: {
      right: 20 * deviceRatio.value,
      itemSize: 15 * deviceRatio.value,
      feature: {
        magicType: {
          show: props.magicType,
          type: ['line', 'bar', 'stack'],
          title: {
            line: '折线图',
            bar: '柱状图',
            stack: '堆叠模式'
          }
        }
      }
    },
    xAxis: {
      type: 'category',
      data: props.xAxisData,
      boundaryGap: false,
      axisLabel: {
        fontSize: 14 * deviceRatio.value,
        color: props.AxisColor,
        formatter: (value: string) => {
          // 假设 value 是 "2025-07-08 12:10:21"
          const [date, time] = value.split(' ')
          return `${date}\n${time}`
        }
      }
    },
    dataZoom: {
      type: 'inside',
      start: props.zoomStart,
      end: props.zoomEnd
    },
    yAxis: [
      {
        type: 'value',
        name: '单位：W / W·mˉ²',
        nameTextStyle: {
          color: props.titleColor,
          fontSize: 14 * deviceRatio.value
        },
        splitLine: { show: false },
        axisTick: {
          show: true // 去掉刻度线 false
        },
        axisLine: { show: true },
        axisLabel: {
          show: true,
          fontSize: 14 * deviceRatio.value,
          color: props.AxisColor
        }
      }
    ],
    grid: {
      left: 60 * deviceRatio.value,
      right: 40 * deviceRatio.value,
      bottom: 50 * deviceRatio.value,
      top: 80 * deviceRatio.value
    },
    legend: {
      data: props.legendData,
      right: 70 * deviceRatio.value,
      top: 35 * deviceRatio.value,
      textStyle: {
        fontSize: 14 * deviceRatio.value,
        color: props.titleColor
      },
      itemWidth: 25 * deviceRatio.value,
      itemHeight: 14 * deviceRatio.value
    },
    series: getSeries()
  }
})

let isCtrlPressed = false
onMounted(() => {
  initChart()
  window.addEventListener('resize', screenAdapter)

  // // 鼠标拖动事件
  Echarts.value.addEventListener('mousedown', handelMousedown)

  Echarts.value.addEventListener('dblclick', handleDoubleClick)
  document.addEventListener('keydown', handleKeyDown, { capture: true })
  document.addEventListener('keyup', handleKeyUp)
})
function handleKeyUp(event: KeyboardEvent) {
  if (event.key === 'Control') {
    isCtrlPressed = false
  }
}

let startIndex: number | null = null
function handelMousedown(e: MouseEvent) {
  if (!Echarts.value || !chartInstance) return
  if (isCtrlPressed) {
    const { dataIndex, seriesData } = getIndex([e.offsetX, e.offsetY])
    if (dataIndex < 0) {
      startIndex = 0
    } else if (dataIndex < seriesData) {
      startIndex = dataIndex
    } else {
      startIndex = null
    }
    document.addEventListener('mouseup', handelMouseup)
  }
}

function handelMouseup(e: MouseEvent) {
  if (!startIndex) return
  let { dataIndex } = getIndex([e.offsetX, e.offsetY])
  if (startIndex === dataIndex) return
  if (startIndex > dataIndex) {
    const temp = dataIndex
    startIndex = dataIndex
    dataIndex = temp
  }
  emits('custom-rect', { startIndex, endIndex: dataIndex })
  document.removeEventListener('mouseup', handelMouseup)
}

function handleDoubleClick(e: MouseEvent) {
  const { dataIndex, seriesData } = getIndex([e.offsetX, e.offsetY])
  if (dataIndex >= 0 && dataIndex < seriesData) {
    emits('custom-dbclick', dataIndex)
  } else {
    console.log('未点击在有效的数据点上')
  }
}

const handleKeyDown = (event: KeyboardEvent) => {
  if (event.key === 'Control') {
    isCtrlPressed = true
  }
}

function getIndex(pointInPixel: [number, number]) {
  const pointInGrid = chartInstance.convertFromPixel('grid', pointInPixel)
  // 获取双击位置的数据索引
  const dataIndex = Math.round(pointInGrid[0])
  let seriesLen = 0
  getSeries().forEach((item: any) => {
    seriesLen =
      seriesLen > (item.data?.length !== undefined ? Number(item.data?.length) : 0) ? seriesLen : item.data?.length
  })
  return { dataIndex, seriesData: seriesLen }
}
onUnmounted(() => {
  window.removeEventListener('resize', screenAdapter)
  Echarts.value?.removeEventListener('mousedown', handelMousedown)
  Echarts.value?.removeEventListener('dblclick', handleDoubleClick)
  document.removeEventListener('mouseup', handelMouseup)
  document.removeEventListener('keydown', handleKeyDown)
  document.removeEventListener('keyup', handleKeyUp)
  chartInstance?.dispose() // 销毁图表实例，释放资源
})
// 响应式更新 option
watch(
  () => option.value,
  (newoption) => {
    if (chartInstance) {
      nextTick(() => {
        chartInstance.resize()
        chartInstance.setOption(newoption, true)
      })
    }
  }
)
function getSeries() {
  return props.yAxisData.map((item) => {
    return {
      name: item.name,
      data: item.data,
      type: 'line',
      smooth: true
    }
  })
}
let chartInstance: any
const initChart = () => {
  chartInstance = echarts.init(Echarts.value)
  renderChart()

  chartInstance.on('magictypechanged', function (params: any) {
    if (params.currentType === 'stack') {
      params.newOption.series.forEach((item: any) => {
        item.areaStyle = {}
      })
    } else {
      params.newOption.series.forEach((item: any) => {
        item.areaStyle = null
      })
    }
    chartInstance.setOption(params.newOption)
  })
}

function renderChart() {
  chartInstance.setOption(option.value)
}

function screenAdapter() {
  windowWidth.value = window.innerWidth
  chartInstance.resize()
  chartInstance.setOption(option.value)
}

function setOption() {
  chartInstance.setOption(option.value)
}
defineExpose({
  setOption
})
</script>

<style scoped lang="scss">
.echart {
  height: 100%;
  width: 100%;
  position: absolute;
}
</style>
